Building a Desktop Application using ZK and JavaFX
Hawk Chen, Engineer, Potix Corporation
July 21, 2022
ZK 9.6.1-Eval
Introduction
Building a desktop application usually requires a different skillset from building a web application, since it runs on a completely different platform from the web. However, in our previous article, Building a Desktop Application using ZK and JCEF, we have already demonstrated the possibility of building a desktop application using ZK and JCEF.
Now, in this article, we are going to talk about an alternative approach - using JavaFX WebView, to bring your ZK applications into the desktop world.
Benefits
Before we start, let’s briefly talk about some benefits of building desktop apps using a web framework:
Reuse web developers' skill
I assume you are already a web developer, if this is the case, you can build a desktop application with your existing web knowledge. No need to learn lots of OS-specific technologies or programming languages.
Reuse existing web applications
Some web applications are also suitable to be used as desktop applications, for example, editors, converters, consumer-related apps…etc. With this approach, you can reuse most of your code without re-implementing it for another OS.
Cross-platform
Java is cross-platform. No need to learn another programming language for specific OS.
Offline support
Desktop applications can easily work offline and access local data. When the network is available, they can then fetch the latest data from the internet as needed.
Demo Application
To demonstrate the idea of building a desktop application using ZK and JavaFX WebView, I built a demo application that generates a QR code and saves the code into a PNG file.
Setup
Follow Run HelloWorld via Maven to setup a Maven project for JavaFX.
Structure
There are 2 entities running in their own thread:
- Spring Boot application: start a ZK web application in Tomcat
- JavaFX App: work as a browser to visit Spring Boot app
I create MyWebApp
with @SpringBootApplication
to start a spring boot application at localhost:8080 in one thread. Then, create MyFxApp
to run JavaFX application in another thread. MyFxApp
will visit the localhost with WebView.
Working with this setup is slightly different from working with a standard web application. In the following sections, I will share with you some of the experiences and findings while building this project.
Building UI with zul
The key benefit of this approach is I can still build UI with ZK components like:
<vlayout style="padding:1em 1em">
Input your URL:
<textbox style="display:block" onChanging="coder.setValue(event.getValue())" value="https://www.zkoss.org" width="100%"/>
<barcode id="coder" type="qr" height="100px" style="cursor:pointer;" sclass="d-block center" />
<button label="Click to Save" sclass="d-block center"/>
</vlayout>
Download QR Code as an Image
In a regular browser, it is straightforward to download a file by clicking a hyperlink to a file. I can even run the code below to download a file:
window.location.href = 'myfile.pdf'
However, none of the standard web downloads works for WebView. In the end, I have to pass the QR code data URL back to Java, convert it into a png, then save it as a file.
Register a Java Object as a JavaScript object
Create ImageSaver to convert data URL into a PNG file:
public class ImageSaver {
public void save(String imageDataUrl) throws IOException {
//save image data URL as a PNG file
}
}
Set ImageSaver
as a member of window
. Then I can access it with window.imageSaver
in JS.
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener() {
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
if (newValue != Worker.State.SUCCEEDED) {
return;
}
JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("imageSaver", imageSaver);
}
}
);
Call Java Method in JS
When users click the QR code image, it will call imageSaver.save()
to save a PNG file.
jq('.z-barcode').on('click', function(){ window.imageSaver.save(getPngDataUrl()); });
Call JavaScript
After saving the QR code file, I notify users with a message by calling Javascript. JavaFX provides a way to run JavaScript in Java:
private void showMessage(String msg){
webView.getEngine().executeScript("zAu.cmd0.showNotification('" + msg +"', 'info', null, null,null, null, 500)");
}
Debug
Java
If you just run mvn javafx:run
under this setup, the breakpoints won’t stop. So I have defined an execution in pom.xml
to enable the Java debugger.
You can run the demo application with mvn javafx:run@debug
to debug with breakpoints.
JavaScript
There is no built-in developer tool in WebView, so it’s better to debug in Chrome. But if you really need to debug js in WebView, you can install JavaFX WebView Debugger.
WebKit
WebView uses the Webkit engine in JDK, so you have to upgrade your JDK in order to upgrade the Webkit. It doesn’t get updated as frequently as Chrome, but on the other hand, you don’t need to worry that your application will break due to an unexpected upgrade.
Source code
You can download the source code of this project from github.
Conclusion
Building cross-platform desktop applications using web technologies is a rising trend. There are also articles out there discussing ideas of building desktop apps with Angular or other web frameworks.
This approach helps developers to reuse their existing web skills and, at the same time leverage some desktop-specific features like offline support or local OS/file access. We hope this article can give you some inspiration and helps you to extend the reach of your web applications beyond the web!
Comments
Copyright © {{{name}}}. This article is licensed under GNU Free Documentation License. |
</includeonly>
This will not display properly unless included in the page.